package com.sis.main.client;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.sis.main.client.intf.IntfSecuritiesPositionService;
import com.sis.main.client.intf.IntfSecuritiesPositionServiceAsync;

public class TableModelSecurities {
	 private HashMap<Integer, DataSecurity> hashmapSecurities = new HashMap <Integer, DataSecurity>();
	 private FlexTable flextableSecurities = new FlexTable();
	 private IntfSecuritiesPositionServiceAsync securitiespositionservice = GWT.create(IntfSecuritiesPositionService.class);
	 
	 TableModelSecurities() {
		    // Create column headers for securities table
		    flextableSecurities.setText(0, 0, "Symbol");
		    flextableSecurities.setText(0, 1, "Last");
		    flextableSecurities.setText(0, 2, "Change");
		    flextableSecurities.setText(0, 3, "Delete");
	 }
	 
	 public FlexTable getSecuritiesFlexTable(){
		 return this.flextableSecurities;
		 
	 }
	 
	 public void getWatchList() {
		    
		    //setup callback to insert security into server datastore
		    AsyncCallback<DataSecurity[]> callback = new AsyncCallback<DataSecurity[]>() {
			      public void onFailure(Throwable caught) {
			        // TODO: Do something with errors.
			      }

			      public void onSuccess(DataSecurity[] dataSecurities) {
			    	  for (int i = 0; i < dataSecurities.length; i++ ){
			    		  DataSecurity dataSecurity = dataSecurities[i];
				    	    // Format the data in the Price and Change fields.
				    	    String priceText = NumberFormat.getFormat("#,##0.00").format(
				    	        dataSecurity.getLast());
				    	    NumberFormat changeFormat = NumberFormat.getFormat("+#,##0.00;-#,##0.00");
				    	    String changeText = changeFormat.format(dataSecurity.getChange());
				    	    String changePercentText = changeFormat.format(dataSecurity.getPercentChange());
				    	    //changePercentText = ((Double) dataSecurity.getPercentChange()).toString();
				    	    // Populate the Price and Change fields with new data.
				    	    flextableSecurities.setText(dataSecurity.getRow(), 1, priceText);
				    	    flextableSecurities.setText(dataSecurity.getRow(), 2, changeText + " (" + changePercentText
				    	        + "%)");
				    	    insertIntoFlexTableWatchList(dataSecurity);
			    	  } //end for dataSecurities		     
			      }//end onSucess
			    };//end AsyncCallback

			    
			    // Make the call to the stock price service.
			    securitiespositionservice.getWatchList(callback);
	 }//end insertWatchList()

	 
	 public void saveSecurity(DataSecurity dataSecurity) {
		    
		    //setup callback to insert security into server datastore
		    AsyncCallback<DataSecurity> callback = new AsyncCallback<DataSecurity>() {
			      public void onFailure(Throwable caught) {
			        // TODO: Do something with errors.
			      }

			      public void onSuccess(DataSecurity dataSecurity) {
			    	  getWatchList();
			      }//end onSucess
			    };//end AsyncCallback

			    
			    // Make the call to the stock price service to save security 
			    //in database
			    securitiespositionservice.saveSecurity(dataSecurity, callback);		    

		    
		    //getQuotes();
	 }//
	 
	 public void deleteSecurity(final int intWatchListID) {
		 
		 
		    //setup callback to insert security into server datastore
		    AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			      public void onFailure(Throwable caught) {
			        // TODO: Do something with errors.
			      }

			      public void onSuccess(Boolean deleteSucess) {
			    	  DataSecurity dataSecurity = hashmapSecurities.get(intWatchListID);
				    	flextableSecurities.removeRow(dataSecurity.getRow());
				    	hashmapSecurities.remove(intWatchListID);
				    	//reset WatchListIDs for all remaining securities
				    	if (hashmapSecurities.size() > 0) {
				    		 Collection<DataSecurity> c = hashmapSecurities.values();
				    		    Iterator<DataSecurity> itr = c.iterator();
				    		    int intRow = 0;
				    		    while (itr.hasNext()) {
				    		      intRow++;
				    		      dataSecurity = itr.next();
				    		      dataSecurity.setRow(intRow);
				    		    }//end while
				    	}//endif 

			      }//end onSucess
			    };//end AsyncCallback

			    
			    // Make the call to the stock price service.
			    DataSecurity dataSecurity = hashmapSecurities.get(intWatchListID);
			    securitiespositionservice.deleteSecurity(dataSecurity, callback);		    
	    	
	 }//end deleteSecurity()

	private Integer setFlexTableWatchListID(DataSecurity dataSecurity) {
		 
		 if ( dataSecurity.getWatchListID() == null ) {
			 	//create ID; note, size may return zero, so plus 1 is added
			 	int ID = hashmapSecurities.size() + 1;
				dataSecurity.setWatchListID(ID);
				return ID;
			 }
		 else {
			return dataSecurity.getWatchListID(); 
		 }
	}
	
	public void insertIntoFlexTableWatchList(DataSecurity dataSecurity) {
	 	final int intWatchListID = setFlexTableWatchListID(dataSecurity); 
	 	
	 	//add stock to table ui data structure
	    hashmapSecurities.put(intWatchListID, dataSecurity);
	    
	    // Add the stock to table view, skipping the column header row
	    //by calling row count() if this is the first assignment of row
   	    int intCol  = 0;
	    if (dataSecurity.getRow() == 0) {
	    	int intRow = flextableSecurities.getRowCount();
	   	    dataSecurity.setRow(intRow);
	    }
	    flextableSecurities.setText(dataSecurity.getRow(), intCol, dataSecurity.getSymbol());

	    // Add a button to remove this stock from the table.
	    Button buttonDeleteSecurity = new Button("x");
	    buttonDeleteSecurity.addClickHandler(new ClickHandler() {
	      public void onClick(ClickEvent event) {
	    	  deleteSecurity(intWatchListID);
	      }//end onclick
	    });
	    flextableSecurities.setWidget(dataSecurity.getRow(), intCol = 3, buttonDeleteSecurity);	
	}

	 
	 private DataSecurity[] getSecurities() {
		    DataSecurity dataSecurity;
		    DataSecurity[] dataSecurities = new DataSecurity[hashmapSecurities.size()];
		    Collection<DataSecurity> c = hashmapSecurities.values();
		    Iterator<DataSecurity> itr = c.iterator();
		    int intRow = 0;
		    while (itr.hasNext()) {
		      dataSecurity = itr.next();
		      dataSecurities[intRow] = dataSecurity;
		      intRow++;
		    }		
		 return dataSecurities;
	 }//end getSecurities

}//end SecuritiesTableModel
